package com.syl.generator.view.controller;

import com.google.gson.Gson;
import com.syl.generator.MainUI;
import com.syl.generator.code.MybatisCodeGenerator;
import com.syl.generator.common.bean.DatabaseBean;
import com.syl.generator.common.bean.InputVerifyBean;
import com.syl.generator.common.bean.TableColumnBean;
import com.syl.generator.common.constant.BaseConstant;
import com.syl.generator.common.dao.SqlLiteMapper;
import com.syl.generator.common.util.ConfigReadUtil;
import com.syl.generator.common.util.DbConnectionUtil;
import com.syl.generator.common.util.StringUtils;
import com.syl.generator.view.bean.GeneratorConfig;
import com.syl.generator.view.enums.FXMLPage;
import com.syl.generator.view.util.AlertUtil;
import com.syl.generator.view.util.UiBaseUtils;
import javafx.collections.ObservableList;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.Parent;
import javafx.scene.control.*;
import javafx.scene.image.ImageView;
import javafx.scene.input.KeyCode;
import javafx.stage.DirectoryChooser;
import lombok.Getter;
import lombok.Setter;
import org.apache.log4j.Logger;

import java.io.File;
import java.net.URL;
import java.util.List;
import java.util.Optional;
import java.util.ResourceBundle;

/**
 * code generator main controller
 *
 * @author syl
 * @create 2018-03-17 11:07
 *
 **/
public class MainUIController implements Initializable {
    private static final Logger LOG = Logger.getLogger(MainUIController.class);

    @Getter
    @Setter
    private Parent parent;
    private Gson gson = new Gson();

    //base end

    @FXML
    private Label connectionLabel;
    @FXML
    private Label systemConfig;
    @FXML
    private Label configsLabel;

    //菜单按钮 end

    @FXML
    private TextField dbTreeSearch;
    @FXML
    private TreeView<TableColumnBean> leftDBTree;//树形菜单
    private TreeItem<TableColumnBean> rootItem = new TreeItem<>();
    private LeftTreeNodeController treeCell;
    //树形菜单 end

    @FXML
    @Getter
    private TextField hideID;
    @FXML
    @Getter
    private TextField tableNameField;
    @FXML
    @Getter
    private TextField tableCommentField;
    @FXML
    @Getter
    private TextField domainObjectNameField;
    @FXML
    private TextField projectFolderField;
    @FXML
    private TextField javaDirectory;//java文件目录
    @FXML
    private TextField xmlDirectory;//xml文件目录
    @FXML
    private TextField functionTarget;//功能目标路径
    @FXML
    private TextField daoName;
    @FXML
    private TextField mapperName;

    //输入框 end

    @FXML
    private CheckBox simpleCheckBox;//简单javabean
    @FXML
    private CheckBox useActualColumnNameCheckbox;//使用元列名
    @FXML
    private CheckBox lombokCheckBox;    //使用lombok
    @FXML
    private CheckBox controllerCheckBox;//
    @FXML
    private CheckBox serviceCheckBox;
    @FXML
    private CheckBox serviceImplCheckBox;
    @FXML
    private Button   generateCodeBtn;
    @FXML
    private Button   diyColumnBtn;


    @Override
    public void initialize(URL location, ResourceBundle resources) {
        new MenuBtnEventController(this,connectionLabel,systemConfig,configsLabel).init();//初始化顶部菜单按钮事件控制器
        this.initFunctionalControl();
        initLeftDBTree();
    }

    /**
     * 定制列事件
     */
    @FXML
    public void openTableColumnCustomizationPage() {
        InputVerifyBean verifyBean = UiBaseUtils.inputIsEmpty(new TextInputControl[]{tableNameField, domainObjectNameField}, getParent());
        if(!verifyBean.isPass()){
            AlertUtil.showInfoAlert(verifyBean.getMessage()+"不能为空");
            return ;
        }
        SelectTableColumnController controller = (SelectTableColumnController)UiBaseUtils.openDialog(SelectTableColumnController.class,diyColumnBtn.getText(),FXMLPage.SELECT_TABLE_COLUMN,true);
        controller.setMainUIController(this);
        controller.initColumnListView();
    }

    /**
     * 初始化左侧控件
     */
    public void initLeftDBTree(){
        MultipleSelectionModel<TreeItem<TableColumnBean>> model = leftDBTree.getSelectionModel();
        model.setSelectionMode(SelectionMode.MULTIPLE);
        leftDBTree.setFocusTraversable(false);
        leftDBTree.setRoot(rootItem);
        leftDBTree.setShowRoot(false);
        leftDBTree.setSelectionModel(model);
        leftDBTree.setCellFactory((TreeView<TableColumnBean> tv) -> treeCell = new LeftTreeNodeController(leftDBTree,this));
        loadSchemaTreeNode();
        //表搜索
        dbTreeSearch.setOnKeyPressed(event ->{
            KeyCode code = event.getCode();
            if(code == KeyCode.ENTER){
                final String text = dbTreeSearch.getText();
                ObservableList<TreeItem<TableColumnBean>> list = rootItem.getChildren();
                for(TreeItem item:list){
                    if(item.isExpanded()){
                        if(text == null || text.isEmpty()){
                            treeCell.loadDbTableNode(item, null);
                            return;
                        }else treeCell.loadDbTableNode(item, text);
                    }
                }
            }
        });
    }

    /**
     * 选择项目所在目录 事件
     */
    @FXML
    public void chooseProjectFolder() {
        DirectoryChooser directoryChooser = new DirectoryChooser();
        File selectedFolder = directoryChooser.showDialog(MainUI.mainStage);
        if (selectedFolder != null) {
            projectFolderField.setText(selectedFolder.getAbsolutePath()+File.separator);
        }
    }

    /**
     * 生成代码事件
     */
    @FXML
    public void generateCode() {
        LOG.info("lock state =============");
        InputVerifyBean verifyBean = UiBaseUtils.inputIsEmpty(new TextInputControl[]{tableNameField, domainObjectNameField,projectFolderField,javaDirectory,functionTarget, daoName, mapperName}, getParent());
        if(!verifyBean.isPass()){
            AlertUtil.showInfoAlert(verifyBean.getMessage()+"不能为空");
            return ;
        }
        GeneratorConfig config = getGeneratorConfigFromUI();
        String tablename = config.getTableName();
        String tableComment = config.getTableComment();
        String[] table_ = tablename.split(";");
        String[] tableComment_ = tableComment.split(";");
        if(StringUtils.isEmpty(tableComment)){
            AlertUtil.showInfoAlert("求求你写下表注释！");
            return ;
        }
        if(table_.length != tableComment_.length){
            AlertUtil.showErrorAlert("注释个数和表个数不符合 (以;为分隔符)");
            return;
        }
        String domin = config.getDomainObjectName();
        String[] domin_ = domin.split(";");
        if(table_.length != domin_.length){
            AlertUtil.showErrorAlert("实体类个数和表个数不符合 (以;为分隔符)");
            return;
        }
        //generateCodeBtn.setDisable(true);
        SqlLiteMapper dao = DbConnectionUtil.getSqliteDao();
        boolean b = dao.isExistSystemConfig();
        if(!b){
            AlertUtil.showInfoAlert("请先进行初始配置" , 2);
            UiBaseUtils.openDialog(SystemConfigController.class,systemConfig.getText(), FXMLPage.SYSTEM_CONFIG, false);
            return;
        }
        LOG.info("==========开始生成代码==========");

        DatabaseBean databaseBean = dao.selectOneDbConnection(config.getDbInfoID());
        new MybatisCodeGenerator(config,databaseBean);//开始生成mybatis 部分代码
        AlertUtil.showInfoAlert("生成完成");
        LOG.info("==========退出生成代码==========");
        generateCodeBtn.setDisable(false);
    }

    /**
     * 保存配置事件
     */
    @FXML
    public void saveGeneratorConfig(){
        InputVerifyBean verifyBean = UiBaseUtils.inputIsEmpty(new TextInputControl[]{tableNameField, domainObjectNameField,projectFolderField,javaDirectory,functionTarget, daoName, mapperName}, getParent());
        if(!verifyBean.isPass()){
            AlertUtil.showInfoAlert(verifyBean.getMessage()+"不能为空");
            return ;
        }
        TextInputDialog dialog = new TextInputDialog("");
        dialog.setTitle("保存当前配置");
        dialog.setContentText("请输入配置名称");
        Optional<String> result = dialog.showAndWait();
        if (result.isPresent()) {
            String name = result.get();
            if (StringUtils.isEmpty(name)) {
                AlertUtil.showErrorAlert("名称不能为空");
                return;
            }
            LOG.info("config name:"+name);
            try {
                GeneratorConfig uiData = getGeneratorConfigFromUI().setName(name);
                String json = gson.toJson(uiData);
                int i;
                SqlLiteMapper dao = DbConnectionUtil.getSqliteDao();
                if(!dao.isExistGeneratorConfig(name))
                    i = dao.saveGeneratorConfig(name,json);
                else
                    i = dao.updateGeneratorConfig(name,json);
                LOG.info("更新操作结果："+i);
            } catch (Exception e) {
                AlertUtil.showErrorAlert("保存配置失败");
            }
        }
    }

    /**
     * 加载数据库树节点
     */
    public void loadSchemaTreeNode() {
        TreeItem rootTreeItem = leftDBTree.getRoot();
        rootTreeItem.getChildren().clear();
        try {
            SqlLiteMapper dao = DbConnectionUtil.getSqliteDao();
            List<DatabaseBean> dbConfigs = dao.selectAllDbConnection();
            for (DatabaseBean bean : dbConfigs) {
                TreeItem<TableColumnBean> treeItem = new TreeItem<>();
                TableColumnBean tableBean = new TableColumnBean();
                tableBean.setTableName(bean.getName());
                treeItem.setValue(tableBean);
                ImageView dbImage = new ImageView(BaseConstant.COMPUTER_ICON);
                dbImage.setFitHeight(16);
                dbImage.setFitWidth(16);
                dbImage.setUserData(bean);
                treeItem.setGraphic(dbImage);
                rootTreeItem.getChildren().add(treeItem);
            }
        } catch (Exception e) {
            LOG.error("connect db failed, reason: {}", e);
            AlertUtil.showErrorAlert(e.getMessage());
        }
    }

    public GeneratorConfig getGeneratorConfigFromUI() {
        GeneratorConfig generatorConfig = new GeneratorConfig();
        generatorConfig.setDbInfoID(hideID.getText());
        generatorConfig.setTableComment(tableCommentField.getText());
        generatorConfig.setProjectFolder(projectFolderField.getText());
        generatorConfig.setDaoName(daoName.getText().replace("*",""));
        generatorConfig.setMapperName(mapperName.getText().replace("*",""));
        generatorConfig.setTableName(tableNameField.getText());
        generatorConfig.setDomainObjectName(domainObjectNameField.getText());
        generatorConfig.setUseActualColumnName(useActualColumnNameCheckbox.isSelected());
        generatorConfig.setSimpleJavaBean(simpleCheckBox.isSelected());
        generatorConfig.setLombok(lombokCheckBox.isSelected());
        generatorConfig.setFunctionTarget(functionTarget.getText());
        generatorConfig.setJavaDirectory(javaDirectory.getText());
        generatorConfig.setXmlDirectory(xmlDirectory.getText());
        generatorConfig.setGeneratorController(controllerCheckBox.isSelected());
        generatorConfig.setGeneratorService(serviceCheckBox.isSelected());
        generatorConfig.setGeneratorServiceImpl(serviceImplCheckBox.isSelected());
        return generatorConfig;
    }

    public void setGeneratorConfigIntoUI(GeneratorConfig generatorConfig) {
        hideID.setText(generatorConfig.getDbInfoID());
        tableCommentField.setText(generatorConfig.getTableComment());
        projectFolderField.setText(generatorConfig.getProjectFolder());
        daoName.setText(generatorConfig.getDaoName());
        mapperName.setText(generatorConfig.getMapperName());
        functionTarget.setText(generatorConfig.getFunctionTarget());
        tableNameField.setText(generatorConfig.getTableName());
        domainObjectNameField.setText(generatorConfig.getDomainObjectName());
        javaDirectory.setText(generatorConfig.getJavaDirectory());
        xmlDirectory.setText(generatorConfig.getXmlDirectory());
        simpleCheckBox.setSelected(generatorConfig.isSimpleJavaBean());
        useActualColumnNameCheckbox.setSelected(generatorConfig.isUseActualColumnName());
        lombokCheckBox.setSelected(generatorConfig.isLombok());
        controllerCheckBox.setSelected(generatorConfig.isGeneratorController());
        serviceCheckBox.setSelected(generatorConfig.isGeneratorService());
        serviceImplCheckBox.setSelected(generatorConfig.isGeneratorServiceImpl());
    }

    /**
     * 初始化功能控制
     */
    private void initFunctionalControl(){
        String ctrlEach = ConfigReadUtil.getYmlString("generate.template.controller.each");
        String serviceBase = ConfigReadUtil.getYmlString("generate.template.service.base");
        String serviceEach = ConfigReadUtil.getYmlString("generate.template.service.each");
        String serviceIBase = ConfigReadUtil.getYmlString("generate.template.service-impl.base");
        String serviceImEach = ConfigReadUtil.getYmlString("generate.template.service-impl.each");
        if(StringUtils.isEmpty(ctrlEach))
            controllerCheckBox.setDisable(true);
        if(StringUtils.isEmptys(serviceBase,serviceEach))
            serviceCheckBox.setDisable(true);
        if(StringUtils.isEmptys(serviceIBase,serviceImEach))
            serviceImplCheckBox.setDisable(true);
    }
}
